/**
 * fileName: MR_YLES_Import_item_barcode_CSV
 * @NApiVersion 2.1
 * @NScriptType MapReduceScript
 */

import {EntryPoints} from 'N/types'
import search = require('N/search')
import record = require('N/record')
import log = require('N/log')
import runtime = require('N/runtime')
import url = require('N/url')
import file = require('N/file')
import email = require('N/email')
import {
    arrChunk,
    getScriptParams,
    parseCsv,
} from "../tools/YLES_Tool";
import {CustomRecordType} from "../tools/YLES_RELATED_RECORDTYPE";
import {
    dealSearch, getCsvFolder,
    ObjectJson
} from "../tools/YLES_SEARCH_TOOL";

export function getInputData(cxt: EntryPoints.MapReduce.getInputDataContext) {
    //1.获取数据
    const logId = getScriptParams('custscript_yles_import_item_barcode_log') as string;
    log.debug({title: 'getInputData logId', details: logId});
    let rec = record.load({type: CustomRecordType().IMPORT_ITEM_BARCODE_LOG, id: logId});
    let st = rec.getValue({fieldId: 'custrecord_yles_status'});
    if (st != '3') throw 'wrong status.';
    let ckSuccessId = rec.getValue({fieldId: 'custrecord_yles_imp_success_csv'}) as number;
    if (ckSuccessId > 0) {
        const ckSuccessFile = file.load({id:ckSuccessId});
        //2:formatData
        let csvData = parseCsv(ckSuccessFile);
        log.debug('get csvData', csvData);

        return csvData;
    }else {
        throw 'there are no deal data.'
    }
}


//map
export function reduce(context: EntryPoints.MapReduce.reduceContext) {
    let k = context.key;
    let v = JSON.parse(context.values[0]);
    log.debug({title: 'reduce k: '+k, details: 'reduce value: ' + context.values[0]});

    try {
        //找到所有已导入的barcode
        let ckInfo = getInfoByItem(k);
        log.debug('map recInfo', ckInfo);
        //创建目标记录
        const {repeatCode} = createRec(ckInfo, v, k);

        //返回barcode已存在的数据
        context.write({key:k,value: {detail:repeatCode,errorMsg:'repeat barcode'}});
    } catch (e) {
        log.error({title: 'map error', details: e});

        //若创建失败，则处理所有此货品的barcode
        // @ts-ignore
        context.write({key:k,value: {detail:v,errorMsg:e.name + ' ' + e.message}});
    }
}


//获取itemId对应的值
function getIdByItemId() {
    const rtn: ObjectJson = {
    };
    const Search = search.create({
        type: 'item',
        filters: [
            ['isinactive', 'is', 'F']
        ],
        columns: [
            {name: 'itemid'}
        ]
    });

    let cb = (res: search.Result, columns: (search.Column | string)[], obj: any) => {
        obj[res.getValue(columns[0]) as string] = res.id;
    }
    dealSearch(Search, cb, rtn);
    return rtn;
}

//找到所有已导入的barcode
function getInfoByItem(no: string) {
    let rt: string[] = [];

    let Search = search.create({
        type: CustomRecordType().ITEM_BARCODE,
        filters: [
            ['custrecord_yles_item.itemid', 'is', no], 'and',
            ['isinactive', 'is', 'F']
        ],
        columns: [
            {name: 'custrecord_yles_barcode', label: 'barcode'}
        ]
    });

    let cb = (res: search.Result, columns: (search.Column | string)[], obj: any) => {
        const barcode = res.getValue(columns[0]) as string;
        obj.push(barcode);
    }
    dealSearch(Search, cb, rt);
    return rt;
}


//创建记录
function createRec(ckInfo: string[], detail: any,itemNo:string) {
    const cIds : string[] = [];
    const itemInfo = getIdByItemId();

    const repeatCode: ObjectJson[] = [];
    //为保证导入，将数组切片，每个记录最多1000行明细
    const tarArr = arrChunk(detail,1000);
    const subId = {sublistId:'recmachcustrecord_yles_head'};

    tarArr.map(d => {
        //导入CSV数据
        const rec = record.create({type: CustomRecordType().HEAD_ITEM_BARCODE});

        //import log
        rec.setValue('custrecord_yles_import_log', getScriptParams('custscript_yles_import_item_barcode_log'));
        d.map((dv:ObjectJson,i) => {
            if (!ckInfo.includes(dv.barcode as string)) {
                rec.setSublistValue({...subId,fieldId: 'custrecord_yles_item',value: itemInfo[itemNo] as string,line: i});
                rec.setSublistValue({...subId,fieldId:'custrecord_yles_barcode',value:dv.barcode as string,line:i});
            }else {
                //校验若在NS系统中存在，则需要处理
                repeatCode.push(dv);
            }
        });

        if (rec.getLineCount({...subId}) > 0) {
            const cid = rec.save({ignoreMandatoryFields: true}).toString();
            cIds.push(cid);
        }else {
            log.error({title:'createRec error',details:itemNo + '：无有效行，忽略创建'});
        }
    })
    return {cIds,repeatCode};
}


export function summarize(summary: EntryPoints.MapReduce.summarizeContext) {
    const logId = getScriptParams('custscript_yles_import_item_barcode_log') as string;
    let fail = false;
    const logVal = {
        custrecord_yles_status: '',
        custrecord_yles_imp_error_csv: '',
        custrecord_yles_end_time: new Date()
    };

    //创建导入错误的CSV文件
    const impErrorCsv = file.create({
        fileType: file.Type.CSV,
        name: 'importErrorCsv_' + new Date().getTime(),
        folder: getCsvFolder() as number
    });
    impErrorCsv.encoding = 'GB18030';//file.Encoding.GB18030;//UTF_8
    impErrorCsv.appendLine({
        value: 'itemId,barcode,原行号,错误提示'
    });
    //汇总导入失败的barcode
    summary.output.iterator().each(function (key, value) {
        if (value) {
            const mpJson = JSON.parse(value);
            if (mpJson.detail && mpJson.detail.length > 0) {
                fail = true;

                mpJson.detail.map((d:{barcode:string,line:number})  => {
                    impErrorCsv.appendLine({
                        value: `${key},${d.barcode},${d.line},${mpJson.errorMsg}`
                    });
                });
            }
        }
        return true;
    });

    if (fail) {
        const impErrorCsvId = impErrorCsv.save().toString();
        log.debug({title:'成功创建导入失败CSV文件ID',details:impErrorCsvId});

        //CSV导入部分失败
        logVal.custrecord_yles_status = '5';
        logVal.custrecord_yles_imp_error_csv = impErrorCsvId;

        //邮件
        sendEmail(impErrorCsvId);
    }else {
        //已完成
        logVal.custrecord_yles_status = '6';

        //邮件
        sendEmail();
    }
    record.submitFields({type: CustomRecordType().IMPORT_ITEM_BARCODE_LOG, id: logId, values: {...logVal}});
    log.debug({title: 'summarize', details: 'end'});
}



//发送邮件
function sendEmail(errId?: string) {
    const logId = getScriptParams('custscript_yles_import_item_barcode_log') as string;
    const userId = runtime.getCurrentUser().id;
    const recipientName = search.lookupFields({type: 'employee', id: userId, columns: ['firstname']})['firstname'];
    const targetUrl = "https://" +
        url.resolveDomain({
            hostType: url.HostType.APPLICATION
        }) +
        url.resolveScript({
            scriptId: 'customscript_yles_import_csv_history_sl',
            deploymentId: 'customdeploy_yles_import_csv_history_sl',
            params: {logId}
        })
    const subject = `【NetSuite Notice】Csv Import Progress is Completed.`;
    const body = `Hi ${recipientName}, 
        Your CSV has imported completed. Please click link below to view results:
        <br/>
        <a href='${targetUrl}'>view csv import results</a>
        <br><br>
        ${errId ? 'There are errors in this progress.Click the link above for more details' : ''}
    `;
    email.send({
        author: userId,
        recipients: userId,
        subject: subject,
        body: body
    });
    log.debug({title: '邮件发送成功', details: 'email success'});
}